//-----------------------------------------------------------------------
// <copyright file="GrantPrivilegeTest.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Unit tests for granting privileges to AD user tasks.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Test
{
    using System;
    using System.IO;
    using Microsoft.Sdc.Tasks.Configuration;
    using Microsoft.Sdc.Tasks.ActiveDirectory;
    using Microsoft.Build.Framework;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Microsoft.Sdc.Tasks.Configuration.ActiveDirectory;

    /// <summary>
    /// Unit tests for AD privilege granting tasks.
    /// </summary>
    [TestClass]
    public class GrantPrivilegeTest
    {
        public GrantPrivilegeTest()
        {
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get { return this.testContextInstance; }
            set { this.testContextInstance = value; }
        }

        [TestMethod] 
        public void TestADUserGrantPrivilegeTask()
        {
            Tasks.ActiveDirectory.User.Create task = new Tasks.ActiveDirectory.User.Create();
            
            //Generate a new random username
            Guid guid = Guid.NewGuid();
            string username = guid.ToString();
            username = username.Replace("-", "").Substring(0, 11);

            if (User.Exists(username))
            {
                Assert.Fail("User already existed");
            }

            string domain = String.Empty;
            string password = "1234$abcd";
            task.UserName = username;
            task.Password = password;
            task.EnsureUser = true;

            bool taskReturnValue = task.Execute();
            Assert.IsTrue( taskReturnValue);

            //Check the user now exists
            bool userExists = User.Exists(username);
            Assert.IsTrue( userExists);

            //Ensure the properties are as entered
            Assert.IsTrue( task.UserName == username);
            Assert.IsTrue( task.Password == password);
            Assert.IsTrue( task.DomainName == domain);
            Assert.IsTrue( task.EnsureUser == true);

            string groupName = this.CreateGroup();

            this.AddUserToGroup(username, groupName);

            //check the user is in the group
            User u = User.Load(username);
            if (!u.IsInGroup(groupName))
            {
                Assert.Fail("Created user is not in the created group");
            }

            try
            {
                this.AddUserToGroupAgain(username, groupName);
                Assert.Fail("Should not have allowed me to add the same user to the group again.");
            }

            catch (ApplicationException)
            {
                Console.WriteLine("Correctly threw ApplicationException on attempting to add user to group again.");
            }

            this.AddUserToGroupEnsuring(username, groupName);

            //Grant this user privileges
            try
            {
                Tasks.ActiveDirectory.User.GrantPrivilege privilegeTask = new Tasks.ActiveDirectory.User.GrantPrivilege();
                
                privilegeTask.DomainName = String.Empty;
                privilegeTask.UserName = username;
                string[] grantedPrivilege = new string[2] { "SeNetworkLogonRight", "SeServiceLogonRight" };
                privilegeTask.Privilege = grantedPrivilege[0];

                bool privilegeGranted = privilegeTask.Execute();
                Assert.IsTrue( privilegeGranted);

                privilegeTask.Privilege = grantedPrivilege[1];
                privilegeGranted = privilegeTask.Execute();
                Assert.IsTrue( privilegeGranted);

                //Load this user up
                User privilegedUser = User.Load(username);

                Assert.IsTrue( privilegedUser.HasPrivilege((Privilege) Enum.Parse(typeof(Privilege), grantedPrivilege[0])));
                Assert.IsTrue( privilegedUser.HasPrivilege((Privilege) Enum.Parse(typeof(Privilege), grantedPrivilege[1])));

                //Ensure the properties are as entered
                Assert.IsTrue(privilegeTask.UserName == username);
                Assert.IsTrue(privilegeTask.DomainName == String.Empty);
                Assert.IsTrue(privilegeTask.Privilege == grantedPrivilege[1]);

            }
            catch (ApplicationException)
            {
                Console.WriteLine("Could not grant user this privilige");
            }


            //Now delete the user
            User user = User.Load(username);
            bool userDeleted = user.Delete();
            Assert.IsTrue(userDeleted);

            //Now delete the group
            Group group = Group.Load(groupName);
            bool groupDeleted = group.Delete();
            Assert.IsTrue( groupDeleted);
        }

        [TestMethod] 
        public void TestUninitializedCreateUserTaskFails()
        {
            Tasks.ActiveDirectory.User.Create task = new Tasks.ActiveDirectory.User.Create();
            
            try
            {
                bool taskReturnValue = task.Execute();
                Assert.Fail("Uninitialised tasks should not succeed.");
            }
            catch (ApplicationException)
            {
                Console.WriteLine("Correctly threw exception");
                Console.WriteLine(((PseudoBuildEngine) task.BuildEngine).PreviousMessage);
            }

        }

        [TestMethod]
        public void TestUninitializedCreateGroupTaskFails()
        {
            Tasks.ActiveDirectory.Group.Create task = new Tasks.ActiveDirectory.Group.Create();
            
            try
            {
                bool taskReturnValue = task.Execute();
                Assert.Fail("Uninitialised tasks should not succeed.");
            }
            catch (ApplicationException)
            {
                Console.WriteLine("Correctly threw exception");
                Console.WriteLine(((PseudoBuildEngine) task.BuildEngine).PreviousMessage);
            }

        }

        [TestMethod] 
        public void TestUninitializedAddUserTaskFails()
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();
           
            try
            {
                bool taskReturnValue = task.Execute();
                Assert.Fail("Uninitialised tasks should not succeed.");
            }
            catch (ApplicationException)
            {
                Console.WriteLine("Correctly threw exception");
                Console.WriteLine(((PseudoBuildEngine) task.BuildEngine).PreviousMessage);
            }

        }

        [TestMethod] 
        public void TestUninitializedGrantPrivilegeTaskFails()
        {
            Tasks.ActiveDirectory.User.GrantPrivilege task = new Tasks.ActiveDirectory.User.GrantPrivilege();
            
            try
            {
                bool taskReturnValue = task.Execute();
                Assert.Fail("Uninitialized tasks should not succeed.");
            }
            catch (ApplicationException)
            {
                Console.WriteLine("Correctly threw exception");
                Console.WriteLine(((PseudoBuildEngine)task.BuildEngine).PreviousMessage);
            }

        }
        
        private void AddUserToGroup(string userName, string groupName)
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();
            
            task.GroupDomain = new string[] { String.Empty };
            task.UserDomain = String.Empty;
            task.UserName = userName;
            task.GroupName = new string[] { groupName };

            bool taskReturn = task.Execute();

            Assert.IsTrue(taskReturn);
            Assert.IsTrue( task.UserDomain.Length == 0);
            Assert.IsTrue(task.UserName == userName);
            Assert.IsTrue(task.GroupName[0] == groupName);
            Assert.IsTrue(task.GroupDomain[0].Length == 0);
        }

        private void AddUserToGroupEnsuring(string userName, string groupName)
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();
            
            task.UserName = userName;
            task.GroupName = new string[] { groupName };
            task.EnsureUserIsInGroup = true;

            bool taskReturn = task.Execute();

            Assert.IsTrue(taskReturn);
            Assert.IsTrue(task.EnsureUserIsInGroup == true);

        }

        private void AddUserToGroupAgain(string userName, string groupName)
        {
            Tasks.ActiveDirectory.Group.AddUser task = new Tasks.ActiveDirectory.Group.AddUser();
            
            task.UserName = userName;
            task.GroupName = new string[] { groupName };
            bool taskReturn = task.Execute();
            //Check that user cannot be added twice
            Assert.IsTrue(!taskReturn);
        }

        private string CreateGroup()
        {
            Tasks.ActiveDirectory.Group.Create task = new Tasks.ActiveDirectory.Group.Create();
            
            //Generate a new random group
            Guid guid = Guid.NewGuid();
            string groupName = guid.ToString();
            groupName = groupName.Replace("-", "").Substring(0, 11);

            if (Group.Exists(groupName))
            {
                Assert.Fail("Group already existed");
            }

            task.GroupName = groupName;
            task.DomainName = String.Empty;
            task.EnsureGroup = false;

            bool taskReturnValue = task.Execute();
            Assert.IsTrue( taskReturnValue);

            //Check the group now exists
            bool groupExists = Group.Exists(groupName);
            Assert.IsTrue( groupExists);

            //Check the properties are as entered
            Assert.IsTrue(task.GroupName == groupName);
            Assert.IsTrue(task.DomainName == String.Empty);
            Assert.IsTrue(task.EnsureGroup == false);

            return groupName;
        }
    }
}

